﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;

namespace Itfort.Net
{
	/// <summary>
	/// Http请求客户端
	/// </summary>
	public class HttpClient
	{
		/// <summary>
		/// 获取HttpWebRequest对象。
		/// </summary>
		/// <param name="uri">地址</param>
		/// <returns>HttpWebRequest对象。</returns>
		public static HttpWebRequest GetRequest(Uri uri)
		{
			HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
			request.Accept = "text/html,application/xhtml+xml,application/xml,*/*";
			request.UserAgent = "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1;)";
			return request;
		}

		/// <summary>
		/// 获取HttpWebRequest对象。
		/// </summary>
		/// <param name="uri">地址。</param>
		/// <param name="httpMethod">请求方式。</param>
		/// <param name="data">数据。</param>
		/// <returns>HttpWebRequest对象。</returns>
		public static HttpWebRequest GetRequest(Uri uri, String httpMethod, String data)
		{
			byte[] bytes = null;
			if (!String.IsNullOrEmpty(data))
			{
				bytes = Encoding.ASCII.GetBytes(data);
			}

			var request = GetRequest(uri);
			request.Method = httpMethod;

			if (httpMethod.ToUpper() == "POST")
			{
				request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
				if (bytes != null)
				{
					request.ContentLength = data.Length;
					var stream = request.GetRequestStream();
					stream.Write(bytes, 0, bytes.Length);
					stream.Close();
				}
			}

			return request;
		}

		/// <summary>
		/// 获取HttpWebResponse对象
		/// </summary>
		/// <param name="uri">地址</param>
		/// <returns></returns>
		public static HttpWebResponse GetResponse(Uri uri)
		{
			return (HttpWebResponse)HttpClient.GetRequest(uri).GetResponse();
		}

		/// <summary>
		/// 获取HttpWebResponse对象
		/// </summary>
		/// <param name="uri">地址。</param>
		/// <param name="httpMethod">请求方式。</param>
		/// <param name="data">数据。</param>
		/// <returns></returns>
		public static HttpWebResponse GetResponse(Uri uri, String httpMethod, String data)
		{
			return (HttpWebResponse)HttpClient.GetRequest(uri, httpMethod, data).GetResponse();
		}

		/// <summary>
		/// 获取Html源码
		/// </summary>
		/// <param name="url">地址。如http://www.itfort.com/default.aspx</param>
		/// <param name="encodingName">编码名称。如utf-8，gb2312</param>
		/// <returns>返回Html源码</returns>
		public static String GetHtml(String url, String encodingName)
		{
			Uri uri = new Uri(url);
			Encoding encoding = Encoding.GetEncoding(encodingName);

			return HttpClient.GetHtml(uri, encoding);
		}

		/// <summary>
		/// 以GET方式获取Html源码
		/// </summary>
		/// <param name="uri">地址</param>
		/// <param name="encoding">编码</param>
		/// <returns>返回Html源码</returns>
		public static String GetHtml(Uri uri, Encoding encoding)
		{
			var response = HttpClient.GetResponse(uri);
			var stream = response.GetResponseStream();

			StreamReader sr = new StreamReader(stream, encoding);
			var html = sr.ReadToEnd();
			sr.Close();
			response.Close();

			return html;
		}

		/// <summary>
		/// 以POST方式获取Html源码。
		/// </summary>
		/// <param name="uri">地址。</param>
		/// <param name="data">Post数据。</param>
		/// <param name="encoding">编码。</param>
		/// <returns>返回Html源码</returns>
		public static String PostHtml(Uri uri, String data, Encoding encoding)
		{
			var response = HttpClient.GetResponse(uri, "POST", data);
			var stream = response.GetResponseStream();

			StreamReader sr = new StreamReader(stream, encoding);
			var html = sr.ReadToEnd();
			sr.Close();
			response.Close();

			return html;
		}

		/// <summary>
		/// 以指定的方式获取HTTP响应内容。
		/// </summary>
		/// <param name="uri">请求地址。</param>
		/// <param name="httpMethod">请求方式。</param>
		/// <param name="encoding">内容编码。</param>
		/// <returns>返回响应内容。</returns>
		public static string RequestContent(Uri uri, string httpMethod, Encoding encoding)
		{
			var response = HttpClient.GetResponse(uri, httpMethod, null);
			var stream = response.GetResponseStream();

			StreamReader sr = new StreamReader(stream, encoding);
			var html = sr.ReadToEnd();
			sr.Close();
			response.Close();

			return html;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="url"></param>
		/// <param name="filename"></param>
		/// <returns></returns>
		public static String CreateAbsoluteUrl(String url, String filename)
		{
			// filename为完整URL
			if (filename.StartsWith("http://", true, null)) return filename;

			if (url.StartsWith("http://", true, null))
			{
				url = url.Substring(7);
			}

			if (url.EndsWith("/"))
			{
				url = url + "index.html";
			}

			String domain;
			if (url.Contains("/"))
			{
				domain = url.Substring(0, url.IndexOf("/"));
			}
			else
			{
				domain = url;
			}

			// filename为绝对路径
			if (filename.StartsWith("/"))
			{
				return "http://" + domain + filename;
			}

			if (filename.StartsWith("../"))
			{
				url = url.Substring(0, url.LastIndexOf("/"));
				while (filename.StartsWith("../"))
				{
					if (url.Contains("/"))
					{
						url = url.Substring(0, url.LastIndexOf("/"));
					}
					filename = filename.Substring(3, filename.Length - 3);
				}
			}
			else
			{
				if (url.Contains("/"))
				{
					url = url.Substring(0, url.LastIndexOf("/"));
				}
			}

			return "http://" + url + "/" + filename;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="url"></param>
		/// <param name="filename"></param>
		public static void DownloadHttpFile(String url, String filename)
		{
			HttpWebResponse response = HttpClient.GetResponse(new Uri(url));
			Stream stream = response.GetResponseStream();
			Byte[] buffer = new Byte[stream.Length];
			stream.Read(buffer, 0, (Int32)stream.Length);
			stream.Close();

			File.WriteAllBytes(filename, buffer);
		}

		//public static string ConvertToFullPath(string source, string uri)
		//{
		//    WebPageUriConverter convert = new WebPageUriConverter();

		//    convert.PageUri = uri;

		//    return convert.ConvertToFullPath(source);
		//}
	}
}
